package com.gitee.baqkft.code.ui.dlg;

import com.gitee.baqkft.code.model.PasswdAlgType;
import com.gitee.baqkft.code.ui.layout.GBC;
import com.gitee.baqkft.code.utils.PasswdUtils;

import javax.swing.*;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;

/**
 * 密码助手工具
 * @Author: chenmingcai
 * @Date 2023/10/16 20:06
 **/

public class PasswordToolFrame extends JFrame
{
    /**
     * 密码长度
     */
    private JTextField lengthField;

    /**
     * 大写字母
     */
    private JCheckBox cbxUpper;

    /**
     * 小写字母
     */
    private JCheckBox cbxLower;

    /**
     * 数字
     */
    private JCheckBox cbxDigits;

    /**
     * 特殊符号
     */
    private JCheckBox cbxSymbols;

    /**
     * 加密算法
     */
    private PasswdAlgType algType;

    private JTextArea passwdArea;

    private JTextArea passwdAlgArea;

    public PasswordToolFrame() throws HeadlessException
    {
        initUI();
    }

    /**
     * 初始化UI
     */
    private void initUI()
    {
        setTitle("密码助手");
        setSize(new Dimension(380, 400));
        setLayout(new GridBagLayout());

        //密码位数
        GBC gbc = new GBC(0, 0, 1, 1).setWeight(0, 0);
        gbc.setFill(GBC.VERTICAL);
        JLabel label = new JLabel("密码长度:");
        add(label, gbc);

        lengthField = new JTextField("8");
        gbc = new GBC(1, 0, 1, 1).setWeight(1, 0);
        gbc.setFill(GBC.BOTH);
        add(lengthField, gbc);

        // 密码要求
        label = new JLabel("密码要求:");
        gbc = new GBC(0, 1, 1, 1).setWeight(0, 0);
        gbc.setFill(GBC.VERTICAL);
        add(label, gbc);

        JPanel panel = createPasswdDemand();
        gbc = new GBC(1, 1, 1, 1).setWeight(1, 0);
        gbc.setFill(GBC.BOTH);
        add(panel, gbc);

        // 密码算法
        label = new JLabel("加密算法:");
        gbc = new GBC(0, 2, 1, 1).setWeight(0, 0);
        gbc.setFill(GBC.VERTICAL);
        add(label, gbc);

        panel = createPasswdAlgorithms();
        gbc = new GBC(1, 2, 1, 1).setWeight(1, 0);
        gbc.setFill(GBC.BOTH);
        add(panel, gbc);

        JButton button = new JButton("生成密码");
        gbc = new GBC(0, 3, 2, 1).setWeight(1, 0)
                .setFill(GBC.HORIZONTAL);
        add(button, gbc);
        button.addActionListener(this::makePasswd);

        label = new JLabel("明文密码:");
        gbc = new GBC(0, 4, 1, 1).setWeight(0, 0);
        gbc.setFill(GBC.VERTICAL);
        add(label, gbc);

        passwdArea = new JTextArea();
        passwdArea.setLineWrap(true);
        gbc = new GBC(1, 4, 1, 1).setWeight(1, 1)
                .setFill(GBC.BOTH);
        add(new JScrollPane(passwdArea), gbc);

        label = new JLabel("加密密码:");
        gbc = new GBC(0, 5, 1, 1).setWeight(0, 0);
        gbc.setFill(GBC.VERTICAL);
        add(label, gbc);

        passwdAlgArea = new JTextArea();
        passwdAlgArea.setLineWrap(true);
        gbc = new GBC(1, 5, 1, 1).setWeight(1, 1)
                .setFill(GBC.BOTH);
        add(new JScrollPane(passwdAlgArea), gbc);
    }

    /**
     * 创建密码要求
     * @return
     */
    private final JPanel createPasswdDemand()
    {
        final JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());

        cbxUpper = new JCheckBox("大写字母");
        GBC gbc= new GBC(0, 0, 1, 1).setWeight(1, 1)
                .setFill(GBC.VERTICAL);
        panel.add(cbxUpper, gbc);
        cbxUpper.setSelected(true);

        cbxLower = new JCheckBox("小写字母");
        gbc = new GBC(1, 0, 1, 1).setWeight(1, 1)
                .setFill(GBC.VERTICAL);
        panel.add(cbxLower, gbc);

        cbxDigits = new JCheckBox("数字");
        gbc = new GBC(2, 0, 1, 1).setWeight(1, 1)
                .setFill(GBC.VERTICAL);
        panel.add(cbxDigits, gbc);

        cbxSymbols = new JCheckBox("特殊符号");
        gbc = new GBC(3, 0, 1, 1).setWeight(1, 1)
                .setFill(GBC.VERTICAL);
        panel.add(cbxSymbols, gbc);

        return panel;
    }

    /**
     * 密码算法
     * @return
     */
    private final JPanel createPasswdAlgorithms()
    {
        final JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());

        final ButtonGroup group = new ButtonGroup();

        JRadioButton rbMD5 = new JRadioButton("MD5");
        GBC gbc = new GBC(0, 0, 1, 1).setWeight(0, 1)
                .setFill(GBC.VERTICAL);
        panel.add(rbMD5, gbc);
        group.add(rbMD5);

        JRadioButton rbBCrypt = new JRadioButton("BCrypt");
        gbc = new GBC(1, 0, 1, 1).setWeight(0, 1)
                .setFill(GBC.VERTICAL);
        panel.add(rbBCrypt, gbc);
        group.add(rbBCrypt);

        final ChangeListener changeListener = e -> {
            if(e.getSource() == rbMD5)
            {
                algType = PasswdAlgType.MD5;
            }
            else
            {
                algType = PasswdAlgType.BCrypt;
            }
        };
        rbMD5.addChangeListener(changeListener);
        rbBCrypt.addChangeListener(changeListener);

        rbBCrypt.setSelected(true);

        return panel;
    }




    /**
     * 生成密码
     * @param event
     */
    private void makePasswd(ActionEvent event)
    {
        int length = Integer.valueOf(lengthField.getText().trim());
        String passwd = PasswdUtils.makeRandomPasswd(length, cbxUpper.isSelected(),
                cbxLower.isSelected(), cbxDigits.isSelected(), cbxSymbols.isSelected());

        passwdArea.setText(passwd);

        String text;
        if(algType == PasswdAlgType.BCrypt)
        {
            text = PasswdUtils.encodeByBCrypt(passwd);
        }
        else
        {
            text = "";
        }

        passwdAlgArea.setText(text);
    }
}
